package com.weipai.springboot.module.dao.impl;

import com.weipai.springboot.enums.ClientType;
import com.weipai.springboot.model.api.GoodsItem;
import com.weipai.springboot.model.api.GoodsItemResult;
import com.weipai.springboot.model.api.ItemSearchProp;
import com.weipai.springboot.module.dao.SolrDao;
import org.apache.solr.client.solrj.response.QueryResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Sort;
import org.springframework.data.solr.core.RequestMethod;
import org.springframework.data.solr.core.SolrTemplate;
import org.springframework.data.solr.core.query.*;
import org.springframework.data.solr.core.query.result.*;
import org.springframework.stereotype.Repository;
import org.springframework.util.StringUtils;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.*;
import java.util.regex.Pattern;

/**
 * @author songmengqiang
 * @create 2018-09-05 14:12
 **/
@Repository
public class SolrDaoImpl implements SolrDao {

    private static final String COLLECTION = "collection1";

    private static final String KEYWORD = "item_keywords";


    private static final String PRODUCTKEYWORD = "productName";
    private static final String SKUNUMBERKEYWORD = "skuNumber";


    @Autowired
    private SolrTemplate solrTemplate;

    @Override
    public void save(GoodsItem item) {
        solrTemplate.saveBean(COLLECTION, item);
        solrTemplate.commit(COLLECTION);
    }

    @Override
    public void save(List<GoodsItem> items) {
        solrTemplate.saveBeans(COLLECTION, items);
        solrTemplate.commit(COLLECTION);
    }

    //从 solr 索引库删除
    @Override
    public void delete(String id) {
        solrTemplate.deleteByIds(COLLECTION, id);
        solrTemplate.commit(COLLECTION);
    }

    // 一键删除所有商品到索引库
    @Override
    public void deleteall() {

    }

    @Override
    public GoodsItemResult query22(Long start,
                                   Integer size,
                                   String sort,
                                   String way) {

        GoodsItemResult result = new GoodsItemResult();
        Query query = new SimpleQuery("*:*");


        //排序
        if (!StringUtils.isEmpty(sort) && !StringUtils.isEmpty(way)) {
//            if ("ASC".equalsIgnoreCase(way)) {
//                Sort sortWay = new Sort(Sort.Direction.ASC, sort);
//                query.addSort(sortWay);
//            }
            if ("DESC".equalsIgnoreCase(way)) {
                Sort sortWay = new Sort(Sort.Direction.DESC, "soldOutGoods");
                query.addSort(sortWay);
            }
        }

        //根据spuNumber产品编号分组,只取一个商品;
        GroupOptions groupOptions = new GroupOptions().addGroupByField("categoryId");
        groupOptions.setLimit(1);
        query.setGroupOptions(groupOptions);
        query.setOffset(start);
        query.setRows(size);

        List<Map<String, Object>> list = new ArrayList<>();
        //获取分组页
        GroupPage<GoodsItem> groupPage = solrTemplate.queryForGroupPage(COLLECTION, query, GoodsItem.class);
        //取spuNumber分组结果
        GroupResult<GoodsItem> groupResult = groupPage.getGroupResult("categoryId");
        //获取分组入口页
        Page<GroupEntry<GoodsItem>> groupEntries = groupResult.getGroupEntries();
        //获取分组入口集合
        List<GroupEntry<GoodsItem>> entryList = groupEntries.getContent();
        for (GroupEntry<GoodsItem> entry : entryList) {
            Map<String, Object> map = new HashMap<>();
            GoodsItem goodsItem = entry.getResult().getContent().get(0);
            map.put("categoryId", goodsItem.getCategoryId());
            map.put("categoryIdImg", goodsItem.getProductCategoryImg());
            map.put("categoryName", goodsItem.getCategoryName());
            //查询上一级分类
            list.add(map);
        }

        result.setCategoryList(list);
        return result;
    }

    @Override
    public GoodsItemResult query(String keyword,
                                 Integer isNews,
                                 Integer isBoutique,
                                 String categoryId,
                                 String brandName,
                                 Integer minPrice,
                                 Integer maxPrice,
                                 String[] prop,
                                 Long start,
                                 Integer size,
                                 String shopId,
                                 String sort,
                                 String way,
                                 String clientType,
                                 List<String> sysProps) {
        GoodsItemResult result = new GoodsItemResult();
        FacetQuery query = new SimpleFacetQuery();
        Pattern pattern = Pattern.compile("^[-\\+]?[\\d]*$");
//        Criteria criteria = new Criteria();
        if (keyword != null && !"".equals(keyword)) {
            if (keyword.indexOf("-") != -1) {
                String substring = keyword.substring(0, keyword.indexOf("-"));
                if (pattern.matcher(substring).matches()) {
                    keyword = substring;
                }
            }
        }


//        char[] chars = keyword.toCharArray();
//        String str = new String();
//        for (int i = 0; i < chars.length; i++) {
//            str += chars[i];
//            if (i != chars.length) {
//                str += "*";
//            }
//        }

        //1 关键字条件
        Criteria criteria = new Criteria(KEYWORD);
        if (StringUtils.isEmpty(keyword)) {
            criteria.contains("");
        } else {
//            criteria.is(keyword);
//            criteria.contains(keyword);
            criteria.is(keyword);
            size = 300;
        }


        //1、按商品分类过滤查询
        if (!StringUtils.isEmpty(categoryId)) {
            FilterQuery filterQuery = new SimpleFilterQuery();
            //创建filterCriteria的Criteria
            Criteria filterCriteria = new Criteria("path").contains(categoryId);
            filterQuery.addCriteria(filterCriteria);
            //添加过滤查询条件
            query.addFilterQuery(filterQuery);
        }

        //1、按店铺 过滤查询
        if (!StringUtils.isEmpty(shopId)) {
            FilterQuery filterQuery = new SimpleFilterQuery();
            //创建filterCriteria的Criteria
            Criteria filterCriteria = new Criteria("shopId").is(shopId);
            filterQuery.addCriteria(filterCriteria);
            //添加过滤查询条件
            query.addFilterQuery(filterQuery);
        }


        //按照品牌过滤查询(与上述的分类一致)
        if (!StringUtils.isEmpty(brandName)) {
            FilterQuery filterQuery = new SimpleFilterQuery();
            //创建filterCriteria的Criteria
            Criteria filterCriteria = new Criteria("brandName").is(brandName);
            filterQuery.addCriteria(filterCriteria);
            //添加过滤查询条件
            query.addFilterQuery(filterQuery);
        }

        //2 是否为新品isNews 0-不是新品 1-是新品
        if (isNews != null && (isNews == 0 || isNews == 1)) {
            FilterQuery filterQuery = new SimpleFilterQuery();
            //创建filterCriteria的Criteria
            Criteria filterCriteria = new Criteria("isNews").is(isNews);
            filterQuery.addCriteria(filterCriteria);
            //添加过滤查询条件
            query.addFilterQuery(filterQuery);
        }


        //2'是否精品，默认为0,   1表示精品',
        if (isBoutique != null && (isBoutique == 0 || isBoutique == 1)) {
            FilterQuery filterQuery = new SimpleFilterQuery();
            //创建filterCriteria的Criteria
            Criteria filterCriteria = new Criteria("isBoutique").is(isBoutique);
            filterQuery.addCriteria(filterCriteria);
            //添加过滤查询条件
            query.addFilterQuery(filterQuery);
        }


        //按价格过滤
        if (minPrice != null && minPrice > 0) {
            FilterQuery filterQuery = new SimpleQuery();
            Criteria filterCriteria = new Criteria("currentPrice").greaterThanEqual(minPrice);
            filterQuery.addCriteria(filterCriteria);
            query.addFilterQuery(filterQuery);
        }
        if (maxPrice != null && maxPrice > 0) {
            FilterQuery filterQuery = new SimpleQuery();
            Criteria filterCriteria = new Criteria("currentPrice").lessThanEqual(maxPrice);
            filterQuery.addCriteria(filterCriteria);
            query.addFilterQuery(filterQuery);
        }

        //过滤属性条件
        if (prop != null) {
            for (String propS : prop) {
                FilterQuery filterQuery = new SimpleFilterQuery();
                //创建filterCriteria的Criteria
                int pos = propS.indexOf("_");
                if (pos == -1 || pos == propS.length() - 1) {
                    continue;
                }
                String fieldName = propS.substring(0, pos) + "_prop";
                String fieldValue = propS.substring(pos + 1);
                Criteria filterCriteria = new Criteria(fieldName).is(fieldValue);
                filterQuery.addCriteria(filterCriteria);
                //添加过滤查询条件
                query.addFilterQuery(filterQuery);
            }
        }


        //排序
        if (!StringUtils.isEmpty(sort) && !StringUtils.isEmpty(way)) {
            if ("ASC".equalsIgnoreCase(way)) {
                Sort sortWay = new Sort(Sort.Direction.ASC, sort);
                query.addSort(sortWay);
            }
            if ("DESC".equalsIgnoreCase(way)) {
                Sort sortWay = new Sort(Sort.Direction.DESC, sort);
                query.addSort(sortWay);
            }
        }


        //增加品牌facet统计
        FacetOptions facetOptions = new FacetOptions().addFacetOnField("brandName");
        boolean isPc = ClientType.PC.getCode().equals(clientType);
        if (isPc) {
            for (String sysProp : sysProps) {
                facetOptions.addFacetOnField(sysProp + "_prop");
            }
        }
        query.setFacetOptions(facetOptions);

        //根据spuNumber产品编号分组,只取一个商品;
        GroupOptions groupOptions = new GroupOptions().addGroupByField("spuNumber");
        groupOptions.setLimit(1);
//        groupOptions.setLimit(100);
        groupOptions.setTotalCount(true);
        groupOptions.setCachePercent(1000);
        groupOptions.addSort(new Sort(Sort.Direction.ASC, "currentPrice"));
        query.setGroupOptions(groupOptions);
        query.addCriteria(criteria);
        query.setOffset(start);
        query.setRows(size);

        List<GoodsItem> list = new ArrayList<>();
        int total = 0;
        //获取分组页
        Page<GoodsItem> page = solrTemplate.queryForFacetPage(COLLECTION, query, GoodsItem.class);
        GroupPage<GoodsItem> groupPage = (GroupPage<GoodsItem>) page;
        //取spuNumber分组结果
        GroupResult<GoodsItem> groupResult = groupPage.getGroupResult("spuNumber");
        //获取分组入口页
        Page<GroupEntry<GoodsItem>> groupEntries = groupResult.getGroupEntries();
        total = Integer.valueOf(groupEntries.getTotalElements() + "");
        //获取分组入口集合
        List<GroupEntry<GoodsItem>> entryList = groupEntries.getContent();
        for (GroupEntry<GoodsItem> entry : entryList) {
            GoodsItem goodsItem = entry.getResult().getContent().get(0);
            list.add(goodsItem);
        }

        //获取facet信息
        List<String> brands = getFacetListByFieldName((FacetPage<GoodsItem>) page, "brandName");
        //获取属性facet
        ItemSearchProp itemSearchProp = new ItemSearchProp();
        if (isPc) {
            for (String sysProp : sysProps) {
            List<String> propList = getFacetListByFieldName((FacetPage<GoodsItem>) page, sysProp + "_prop");
            itemSearchProp.putAll(sysProp, propList);
        }
    }

        //调整solr排序
        //排序
        if (!StringUtils.isEmpty(sort) && !StringUtils.isEmpty(way)) {
            try {
                sortResult(list, sort, way);
            } catch (NoSuchMethodException e) {
                e.printStackTrace();
            }
        }
        List<GoodsItem> listNew = new ArrayList<>();


        if (keyword != null && !pattern.matcher(keyword).matches()) {
            char[] chars = keyword.toCharArray();
            if (!StringUtils.isEmpty(keyword)) {
                for (int i = 0; i < list.size(); i++) {
                    String productName = list.get(i).getProductName();
                    String shopName = list.get(i).getShopName();
                    String brandNameNew = list.get(i).getBrandName();
                    String skuNumber = list.get(i).getSkuNumber();
                    boolean flag = true;
                    for (int j = 0; j < chars.length; j++) {
                        if (productName.indexOf(chars[j]) == -1) {
                            flag = false;
                            break;
                        }
                        // && shopName.indexOf(chars[j]) == -1 && brandNameNew.indexOf(chars[j]) == -1 && skuNumber.indexOf(chars[j]) == -1
//                    if(shopName.indexOf(chars[j])== -1){
//                        flag = false;
//                        break;
//                    }
//                    if(brandNameNew.indexOf(chars[j])== -1){
//                        flag = false;
//                        break;
//                    }
//                    if(skuNumber.indexOf(chars[j])== -1){
//                        flag = false;
//                        break;
//                    }
                    }
                    if (flag) {
                        listNew.add(list.get(i));
                    }
                }
            }
            result.setItems(listNew);
            result.setTotal(listNew.size());
        } else {
            result.setItems(list);
            result.setTotal(total);
        }


        //品牌
        result.setSearchProp(itemSearchProp);
        result.setBrands(brands);

        return result;
    }


    private void sortResult(List<GoodsItem> list, String sortField, String way) throws NoSuchMethodException {
        //按 条件关键字 搜索
        String getMethodStr = "get" + toUpperCaseFirstOne(sortField);
        Method getMethod = GoodsItem.class.getMethod(getMethodStr);

        boolean isReverseOrder = "DESC".equalsIgnoreCase(way);//是否倒序
        Collections.sort(list, new Comparator<GoodsItem>() {
            @Override
            public int compare(GoodsItem o1, GoodsItem o2) {
                int compareValue = 0;
                Object o1Val = null;
                Object o2Val = null;
                try {
                    o1Val = getMethod.invoke(o1);
                    o2Val = getMethod.invoke(o2);
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                } catch (InvocationTargetException e) {
                    e.printStackTrace();
                }
                if (o1Val == null) {
                    return -1;
                } else if (o2Val == null) {
                    return 1;
                } else {
                    if (o1Val instanceof String) {
                        compareValue = ((String) o1Val).compareTo((String) o2Val);
                    } else if (o1Val instanceof Integer) {
                        compareValue = ((Integer) o1Val).compareTo((Integer) o2Val);
                    }
                }

                if (isReverseOrder) {//倒序
                    compareValue = -compareValue;
                }
                return compareValue;
            }
        });
    }

    private String toUpperCaseFirstOne(String s) {
        if (Character.isUpperCase(s.charAt(0)))
            return s;
        else
            return (new StringBuilder()).append(Character.toUpperCase(s.charAt(0))).append(s.substring(1)).toString();
    }

    private List<String> getFacetListByFieldName(FacetPage<GoodsItem> page, String fieldName) {
        FacetPage<GoodsItem> facetPage = (FacetPage<GoodsItem>) page;
        Page<FacetFieldEntry> facetFieldEntryPage = facetPage.getFacetResultPage(fieldName);
        List<FacetFieldEntry> facetFieldEntryList = facetFieldEntryPage.getContent();
        List<String> list = new ArrayList<>();
        for (FacetFieldEntry entry : facetFieldEntryList) {
            list.add(entry.getValue());
        }
        return list;
    }


    @Override
    public GoodsItemResult queryV2(String keyword,
                                 Integer isNews,
                                 Integer isBoutique,
                                 String categoryId,
                                 String brandName,
                                 Integer minPrice,
                                 Integer maxPrice,
                                 String[] prop,
                                 Long start,
                                 Integer size,
                                 String shopId,
                                 String sort,
                                 String way,
                                 String clientType,
                                 List<String> sysProps,Integer isHomePage) {
        if (isHomePage==null||isHomePage!=0){
            isHomePage=1;
        }
        GoodsItemResult result = new GoodsItemResult();
        FacetQuery query = new SimpleFacetQuery();
        Pattern pattern = Pattern.compile("^[-\\+]?[\\d]*$");
//        Criteria criteria = new Criteria();
        if (keyword != null && !"".equals(keyword)) {
            if (keyword.indexOf("-") != -1) {
                String substring = keyword.substring(0, keyword.indexOf("-"));
                if (pattern.matcher(substring).matches()) {
                    keyword = substring;
                }
            }
        }


//        char[] chars = keyword.toCharArray();
//        String str = new String();
//        for (int i = 0; i < chars.length; i++) {
//            str += chars[i];
//            if (i != chars.length) {
//                str += "*";
//            }
//        }

        //1 关键字条件
        Criteria criteria = new Criteria(KEYWORD);
        if (StringUtils.isEmpty(keyword)) {
            criteria.contains("");
        } else {
//            criteria.is(keyword);
//            criteria.contains(keyword);
            criteria.is(keyword);
            size = 300;
        }


        //1、按商品分类过滤查询
        if (!StringUtils.isEmpty(categoryId)) {
            FilterQuery filterQuery = new SimpleFilterQuery();
            //创建filterCriteria的Criteria
            Criteria filterCriteria = new Criteria("path").contains(categoryId);
            filterQuery.addCriteria(filterCriteria);
            //添加过滤查询条件
            query.addFilterQuery(filterQuery);
        }

        //1、按店铺 过滤查询
        if (!StringUtils.isEmpty(shopId)) {
            FilterQuery filterQuery = new SimpleFilterQuery();
            //创建filterCriteria的Criteria
            Criteria filterCriteria = new Criteria("shopId").is(shopId);
            filterQuery.addCriteria(filterCriteria);
            //添加过滤查询条件
            query.addFilterQuery(filterQuery);
        }


        //按照品牌过滤查询(与上述的分类一致)
        if (!StringUtils.isEmpty(brandName)) {
            FilterQuery filterQuery = new SimpleFilterQuery();
            //创建filterCriteria的Criteria
            Criteria filterCriteria = new Criteria("brandName").is(brandName);
            filterQuery.addCriteria(filterCriteria);
            //添加过滤查询条件
            query.addFilterQuery(filterQuery);
        }

        //2 是否为新品isNews 0-不是新品 1-是新品
        if (isNews != null && (isNews == 0 || isNews == 1)) {
            FilterQuery filterQuery = new SimpleFilterQuery();
            //创建filterCriteria的Criteria
            Criteria filterCriteria = new Criteria("isNews").is(isNews);
            filterQuery.addCriteria(filterCriteria);
            //添加过滤查询条件
            query.addFilterQuery(filterQuery);
        }


        //2'是否精品，默认为0,   1表示精品',
        if (isBoutique != null && (isBoutique == 0 || isBoutique == 1)) {
            FilterQuery filterQuery = new SimpleFilterQuery();
            //创建filterCriteria的Criteria
            Criteria filterCriteria = new Criteria("isBoutique").is(isBoutique);
            filterQuery.addCriteria(filterCriteria);
            //添加过滤查询条件
            query.addFilterQuery(filterQuery);
        }


        //按价格过滤
        if (minPrice != null && minPrice > 0) {
            FilterQuery filterQuery = new SimpleQuery();
            Criteria filterCriteria = new Criteria("currentPrice").greaterThanEqual(minPrice);
            filterQuery.addCriteria(filterCriteria);
            query.addFilterQuery(filterQuery);
        }
        if (maxPrice != null && maxPrice > 0) {
            FilterQuery filterQuery = new SimpleQuery();
            Criteria filterCriteria = new Criteria("currentPrice").lessThanEqual(maxPrice);
            filterQuery.addCriteria(filterCriteria);
            query.addFilterQuery(filterQuery);
        }

        //过滤属性条件
        if (prop != null) {
            for (String propS : prop) {
                FilterQuery filterQuery = new SimpleFilterQuery();
                //创建filterCriteria的Criteria
                int pos = propS.indexOf("_");
                if (pos == -1 || pos == propS.length() - 1) {
                    continue;
                }
                String fieldName = propS.substring(0, pos) + "_prop";
                String fieldValue = propS.substring(pos + 1);
                Criteria filterCriteria = new Criteria(fieldName).is(fieldValue);
                filterQuery.addCriteria(filterCriteria);
                //添加过滤查询条件
                query.addFilterQuery(filterQuery);
            }
        }


        //排序
        if (!StringUtils.isEmpty(sort) && !StringUtils.isEmpty(way)) {
            if ("ASC".equalsIgnoreCase(way)) {
                Sort sortWay = new Sort(Sort.Direction.ASC, sort);
                query.addSort(sortWay);
            }
            if ("DESC".equalsIgnoreCase(way)) {
                Sort sortWay = new Sort(Sort.Direction.DESC, sort);
                query.addSort(sortWay);
            }
        }


        //增加品牌facet统计
        FacetOptions facetOptions = new FacetOptions().addFacetOnField("brandName");
        boolean isPc = ClientType.PC.getCode().equals(clientType);
        if (isPc) {
            for (String sysProp : sysProps) {
                facetOptions.addFacetOnField(sysProp + "_prop");
            }
        }
        query.setFacetOptions(facetOptions);

        //根据spuNumber产品编号分组,只取一个商品;
        GroupOptions groupOptions = new GroupOptions().addGroupByField("spuNumber");
        groupOptions.setLimit(1);
        groupOptions.setTotalCount(true);
//        groupOptions.setLimit(100);
        groupOptions.addSort(new Sort(Sort.Direction.ASC, "currentPrice"));
        query.setGroupOptions(groupOptions);
        query.addCriteria(criteria);


        List<GoodsItem> list = new ArrayList<>();
        int total = 0;
        //获取分组页
        query.setOffset(start);
        query.setRows(size);
        Page<GoodsItem> page = solrTemplate.queryForFacetPage(COLLECTION, query, GoodsItem.class);

        GroupPage<GoodsItem> groupPage = (GroupPage<GoodsItem>) page;


        //取spuNumber分组结果
        GroupResult<GoodsItem> groupResult = groupPage.getGroupResult("spuNumber");
        //获取分组入口页
        Page<GroupEntry<GoodsItem>> groupEntries = groupResult.getGroupEntries();
        total = Integer.valueOf(groupEntries.getTotalElements() + "");
        //获取分组入口集合
        List<GroupEntry<GoodsItem>> entryList = groupEntries.getContent();
        int count=0;
        count=total;
        if(entryList.size()>0&&entryList!=null){
            if(size+start.intValue()>entryList.size()){
                entryList=entryList.subList(start.intValue(),entryList.size());
            }else {
                entryList=entryList.subList(start.intValue(),size+start.intValue());
            }


        }
        for (GroupEntry<GoodsItem> entry : entryList) {
            GoodsItem goodsItem = entry.getResult().getContent().get(0);
            list.add(goodsItem);
        }

        //获取facet信息
        List<String> brands = getFacetListByFieldName((FacetPage<GoodsItem>) page, "brandName");
        //获取属性facet
        ItemSearchProp itemSearchProp = new ItemSearchProp();
        if (isPc) {
            for (String sysProp : sysProps) {
                List<String> propList = getFacetListByFieldName((FacetPage<GoodsItem>) page, sysProp + "_prop");
                itemSearchProp.putAll(sysProp, propList);
            }
        }

        //调整solr排序
        //排序
        if (!StringUtils.isEmpty(sort) && !StringUtils.isEmpty(way)) {
            try {
                sortResult(list, sort, way);
            } catch (NoSuchMethodException e) {
                e.printStackTrace();
            }
        }
        List<GoodsItem> listNew = new ArrayList<>();


        if (keyword != null && !pattern.matcher(keyword).matches()) {
            char[] chars = keyword.toCharArray();
            if (!StringUtils.isEmpty(keyword)) {
                for (int i = 0; i < list.size(); i++) {
                    String productName = list.get(i).getProductName();
                    String shopName = list.get(i).getShopName();
                    String brandNameNew = list.get(i).getBrandName();
                    String skuNumber = list.get(i).getSkuNumber();
                    boolean flag = true;
                    for (int j = 0; j < chars.length; j++) {
                        if (productName.indexOf(chars[j]) == -1) {
                            flag = false;
                            break;
                        }
                        // && shopName.indexOf(chars[j]) == -1 && brandNameNew.indexOf(chars[j]) == -1 && skuNumber.indexOf(chars[j]) == -1
//                    if(shopName.indexOf(chars[j])== -1){
//                        flag = false;
//                        break;
//                    }
//                    if(brandNameNew.indexOf(chars[j])== -1){
//                        flag = false;
//                        break;
//                    }
//                    if(skuNumber.indexOf(chars[j])== -1){
//                        flag = false;
//                        break;
//                    }
                    }
                    if (flag) {
                        listNew.add(list.get(i));
                    }
                }
            }
            result.setItems(listNew);
            result.setTotal(listNew.size());
        } else {
            result.setItems(list);
            result.setTotal(count);

        }


        //品牌
        result.setSearchProp(itemSearchProp);
        result.setBrands(brands);

        return result;
    }


}
